"""Busca Local Monótona - PRIMEIRA MELHORA"""
import time
import random
import pandas as pd
from functools import reduce
# n = quantidade de tasks = m^r
# i = tempo de cada tarefa indo de 1 a 100
# r = valor randomizado de tarefas {1.5,2.0}
# m = número de máquinas {10, 20, 50}

def getProximaMaquina(maquinas):
    return max(maquinas, key=lambda it: getMakespan(maquinas, maquinas.index(it)))

def mostra(maquinas):
    for i in range(len(maquinas)):
        print("Máquina", i + 1, "com makespan", getMakespan(maquinas, i))
        print(maquinas[i])
        print()

def getMakespan(maquinas, i):
    return reduce(lambda a, b: a + b, maquinas[i], 0)

def init():
    possibMaquina = [10, 20, 50] # Lista de máquinas.
    rTarefas = [1.5, 2] # Expoente de grandeza da quantidade de tarefas.
    salvar = []

    for m in possibMaquina:
        for r in rTarefas:
            quantidadeTarefas = int(m ** r)
            tarefas = [random.randint(1, 100) for i in range(quantidadeTarefas)]
            maquinas = [[] for i in range(m)]
            maquinas[0] = tarefas
            contador = 1
            inicio = time.time()
            while movimenta(maquinas):
                contador += 1
            fim = time.time()
            mostra(maquinas)
            
            maquinaComMaiorMakespan = getProximaMaquina(maquinas)
            indiceMakespan = maquinas.index(maquinaComMaiorMakespan)

            salvar.append({
                "iteracoes": contador,
                "maquinas": m,
                "nTarefas": quantidadeTarefas,
                "r": r,
                "%Perturbacao": "null",
                "Makespan": getMakespan(maquinas,indiceMakespan),
                "tempo": fim - inicio
            })

    print(salvar)
    df = pd.DataFrame(salvar, columns=['iteracoes', 'maquinas', 'nTarefas', 'r', '%Perturbacao', 'Makespan', 'tempo'])
    print(df)
    df.to_csv('bmon.csv', encoding='utf-8', index=False)

def movimenta(maquinas):
    """Atribui tarefas a máquinas."""
    maquinaRemover = getProximaMaquina(maquinas)
    maquinaMover = maquinaRemover.pop()

    for i in range(len(maquinas)):
        maquinaDestino = maquinas[i]

        if maquinas.index(maquinaRemover) == i:
            continue
        if (getMakespan(maquinas, i) + maquinaMover) < getMakespan(maquinas, maquinas.index(
                maquinaRemover)) + maquinaMover:
            maquinaDestino.append(maquinaMover)
            return True
    maquinaRemover.append(maquinaMover)
    return False
